package server;
import java.util.HashMap;
import java.util.Map;
import java.util.Map.Entry;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.BlockingQueue;

import Util.Task;
import Util.TaskQueue;
import entity.ChatMessage;
import entity.MsgQueue;
import entity.UserChannels;
import io.netty.channel.Channel;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInboundHandlerAdapter;
import io.netty.channel.group.ChannelGroup;
import io.netty.channel.group.DefaultChannelGroup;
import io.netty.util.concurrent.GlobalEventExecutor;
import messagePacket.Packet;
 
public class ChattingServeHandler extends ChannelInboundHandlerAdapter{
	
    public static ChannelGroup channels=new DefaultChannelGroup(GlobalEventExecutor.INSTANCE);
    public static UserChannels uc=new UserChannels();
    
    public static MsgQueue msgQueue = new MsgQueue();
  
    public static Map<String, HashMap<Integer, String>> friends = new HashMap<String, HashMap<Integer, String>>();

    @Override 
    public void handlerAdded(ChannelHandlerContext ctx) throws Exception {
        Channel newchannel=ctx.channel();
        System.out.println("Welcome new Client"+newchannel.remoteAddress());
        channels.add(newchannel);
        System.out.println("On-line Client amount--->" + channels.size());
    }
 
    @Override
    public void handlerRemoved(ChannelHandlerContext ctx) throws Exception {
        Channel newchannel =ctx.channel();
        // traverse the channels,inform other Client,this Client is Off-line
        for(Channel ch:channels) {
            if (ch != newchannel) {
                ch.writeAndFlush(newchannel.remoteAddress() + "Client Off-line");
            }
        }
        // remove this Client 
        channels.remove(newchannel);
 
    }
 
        @Override 
	    public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
	        Channel newchannel = ctx.channel();
	        System.out.println("----->" + msg.toString());
	        Packet cmsg=(Packet)msg;
	        // add the task to the Queue
	        Task task = new Task(cmsg, newchannel);
	        TaskQueue.inQueue(task);
	        
	    }


    @Override 
    public void channelActive(ChannelHandlerContext ctx) throws Exception {
        Channel newchannel=ctx.channel();
        System.out.println("["+newchannel.remoteAddress()+"]On-line");
    }
 
    @Override
    public void channelInactive(ChannelHandlerContext ctx) throws Exception {
        Channel newchannel=ctx.channel();
        System.out.println("["+newchannel.remoteAddress()+"]Off-line");
        uc.removeChannel(ctx.channel());
    }
 
    @Override 
    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
        Channel newchannel=ctx.channel();
        System.out.println("["+newchannel.remoteAddress()+"]communicate exception");
        System.out.println(cause.getMessage());
        newchannel.close();
    }
}
